"""
SQL编译器 V3.0
完全重新设计，整合词法、语法、语义分析
"""

from typing import Dict, Any, List, Optional
try:
    from .lexer_v3 import LexerV3
    from .parser_v3 import ParserV3
    from .semantic_v3 import SemanticAnalyzerV3
except ImportError:
    from lexer_v3 import LexerV3
    from parser_v3 import ParserV3
    from semantic_v3 import SemanticAnalyzerV3

class SQLCompilerV3:
    """SQL编译器 V3.0"""
    
    def __init__(self):
        """初始化SQL编译器"""
        self.lexer = LexerV3()
        self.parser = ParserV3()
        self.semantic_analyzer = SemanticAnalyzerV3()
        
        # 编译统计
        self.compile_stats = {
            'total_statements': 0,
            'successful_compiles': 0,
            'lexical_errors': 0,
            'syntax_errors': 0,
            'semantic_errors': 0
        }
    
    def compile(self, sql: str) -> Dict[str, Any]:
        """编译SQL语句"""
        self.compile_stats['total_statements'] += 1
        
        result = {
            'success': False,
            'tokens': [],
            'ast': None,
            'semantic_result': None,
            'execution_plan': None,
            'errors': [],
            'warnings': []
        }
        
        try:
            # 1. 词法分析
            tokens = self.lexer.tokenize(sql)
            result['tokens'] = tokens
            
            if not tokens:
                result['errors'].append("词法分析失败：没有识别到任何token")
                self.compile_stats['lexical_errors'] += 1
                return result
            
            # 2. 语法分析
            ast = self.parser.parse(sql)
            if not ast:
                result['errors'].extend(self.parser.errors)
                self.compile_stats['syntax_errors'] += 1
                return result
            
            result['ast'] = ast
            
            # 3. 语义分析
            semantic_result = self.semantic_analyzer.analyze(ast)
            result['semantic_result'] = semantic_result
            
            if not semantic_result['valid']:
                result['errors'].extend(semantic_result['errors'])
                self.compile_stats['semantic_errors'] += 1
                return result
            
            result['warnings'].extend(semantic_result.get('warnings', []))
            
            # 4. 生成执行计划
            execution_plan = self._generate_execution_plan(ast, semantic_result)
            result['execution_plan'] = execution_plan
            
            result['success'] = True
            self.compile_stats['successful_compiles'] += 1
            
        except Exception as e:
            result['errors'].append(f"编译异常: {str(e)}")
        
        return result
    
    def _generate_execution_plan(self, ast: Dict[str, Any], semantic_result: Dict[str, Any]) -> Dict[str, Any]:
        """生成执行计划"""
        if ast['type'] == 'CREATE_TABLE':
            return {
                'type': 'CREATE_TABLE',
                'table_name': ast['table_name'],
                'schema': semantic_result['schema']
            }
        
        elif ast['type'] == 'INSERT':
            return {
                'type': 'INSERT',
                'table_name': ast['table_name'],
                'columns': semantic_result['columns'],
                'values': semantic_result['values']
            }
        
        elif ast['type'] == 'SELECT':
            # 构建SELECT执行计划，包含所有新功能
            select_plan = {
                'type': 'SELECT',
                'table_name': ast['table_name'],
                'columns': semantic_result['columns'],
                'where_clause': semantic_result['where_clause'],
                # 新增功能支持
                'group_by': semantic_result.get('group_by', []),
                'having_clause': semantic_result.get('having_clause'),
                'order_by': semantic_result.get('order_by', []),
                'aggregate_columns': semantic_result.get('aggregate_columns', []),
                'alias_map': semantic_result.get('alias_map', {})
            }
            return select_plan
        
        elif ast['type'] == 'DELETE':
            return {
                'type': 'DELETE',
                'table_name': ast['table_name'],
                'where_clause': semantic_result['where_clause']
            }
        
        elif ast['type'] == 'UPDATE':
            return {
                'type': 'UPDATE',
                'table_name': ast['table_name'],
                'assignments': semantic_result['assignments'],
                'where_clause': semantic_result['where_clause']
            }
        
        elif ast['type'] == 'DROP_TABLE':
            return {
                'type': 'DROP_TABLE',
                'table_name': ast['table_name']
            }
        
        else:
            raise ValueError(f"不支持的AST类型: {ast['type']}")
    
    def compile_file(self, file_path: str) -> List[Dict[str, Any]]:
        """编译SQL文件"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                sql_content = f.read()
            
            # 分割SQL语句
            statements = self._split_sql_statements(sql_content)
            
            results = []
            for statement in statements:
                if statement.strip():
                    result = self.compile(statement.strip())
                    results.append(result)
            
            return results
        
        except Exception as e:
            return [{'success': False, 'errors': [f"文件读取错误: {str(e)}"]}]
    
    def _split_sql_statements(self, sql_content: str) -> List[str]:
        """分割SQL语句"""
        statements = []
        current_statement = ""
        in_string = False
        string_char = None
        
        i = 0
        while i < len(sql_content):
            char = sql_content[i]
            
            if not in_string:
                if char in ["'", '"']:
                    in_string = True
                    string_char = char
                    current_statement += char
                elif char == ';':
                    current_statement += char
                    statements.append(current_statement.strip())
                    current_statement = ""
                else:
                    current_statement += char
            else:
                current_statement += char
                if char == string_char:
                    # 检查是否是转义字符
                    if i > 0 and sql_content[i-1] == '\\':
                        pass  # 转义字符，继续
                    else:
                        in_string = False
                        string_char = None
            
            i += 1
        
        # 添加最后一个语句
        if current_statement.strip():
            statements.append(current_statement.strip())
        
        return statements
    
    def get_catalog(self) -> Dict[str, Any]:
        """获取系统目录"""
        return self.semantic_analyzer.get_catalog()
    
    def print_catalog(self):
        """打印系统目录"""
        self.semantic_analyzer.print_catalog()
    
    def get_compile_stats(self) -> Dict[str, Any]:
        """获取编译统计信息"""
        return self.compile_stats.copy()
    
    def reset_stats(self):
        """重置编译统计"""
        self.compile_stats = {
            'total_statements': 0,
            'successful_compiles': 0,
            'lexical_errors': 0,
            'syntax_errors': 0,
            'semantic_errors': 0
        }
    
    def print_compile_result(self, result: Dict[str, Any]):
        """打印编译结果"""
        print("=" * 80)
        print("SQL编译结果")
        print("=" * 80)
        
        if result['success']:
            print("✅ 编译成功")
        else:
            print("❌ 编译失败")
        
        # 打印错误
        if result['errors']:
            print("\n错误信息:")
            for error in result['errors']:
                print(f"  ❌ {error}")
        
        # 打印警告
        if result['warnings']:
            print("\n警告信息:")
            for warning in result['warnings']:
                print(f"  ⚠️  {warning}")
        
        # 打印token流
        if result['tokens']:
            print(f"\n词法分析结果 ({len(result['tokens'])} 个token):")
            print("-" * 60)
            for token in result['tokens']:
                print(f"  {token['type']:<15} {str(token['value']):<20} 行{token['line']} 列{token['column']}")
        
        # 打印AST
        if result['ast']:
            print("\n语法分析结果 (AST):")
            print("-" * 60)
            self.parser.print_ast(result['ast'])
        
        # 打印执行计划
        if result['execution_plan']:
            print("\n执行计划:")
            print("-" * 60)
            self._print_execution_plan(result['execution_plan'])
        
        print("=" * 80)
    
    def _print_execution_plan(self, plan: Dict[str, Any]):
        """打印执行计划"""
        if plan['type'] == 'CREATE_TABLE':
            print(f"CREATE_TABLE: {plan['table_name']}")
            print("  列定义:")
            for col_name, col_info in plan['schema']['columns'].items():
                col_type = col_info['type']['type']
                if col_info['type'].get('length'):
                    col_type += f"({col_info['type']['length']})"
                print(f"    {col_name}: {col_type}")
        
        elif plan['type'] == 'INSERT':
            print(f"INSERT INTO: {plan['table_name']}")
            if plan['columns']:
                print(f"  列: {', '.join(plan['columns'])}")
            print(f"  值: {[v['value'] for v in plan['values']]}")
        
        elif plan['type'] == 'SELECT':
            print(f"SELECT FROM: {plan['table_name']}")
            
            # 打印列信息
            if plan['columns'] == '*':
                print("  列: *")
            else:
                # 处理聚合函数和别名
                formatted_columns = []
                for col in plan['columns']:
                    # 处理别名映射
                    if col in plan['alias_map']:
                        formatted_columns.append(f"{col} (别名 for {plan['alias_map'][col]})")
                    else:
                        formatted_columns.append(col)
                
                print(f"  列: {', '.join(formatted_columns)}")
            
            # 打印WHERE条件
            if plan['where_clause']:
                print("  WHERE条件: 已设置")
            
            # 打印GROUP BY子句
            if plan.get('group_by') and plan['group_by']:
                print(f"  GROUP BY: {', '.join(plan['group_by'])}")
            
            # 打印HAVING条件
            if plan.get('having_clause'):
                print("  HAVING条件: 已设置")
            
            # 打印ORDER BY子句
            if plan.get('order_by') and plan['order_by']:
                order_exprs = []
                for expr in plan['order_by']:
                    order_exprs.append(f"{expr['column']} {expr['direction']}")
                print(f"  ORDER BY: {', '.join(order_exprs)}")
            
            # 打印聚合函数信息
            if plan.get('aggregate_columns') and plan['aggregate_columns']:
                agg_funcs = []
                for agg in plan['aggregate_columns']:
                    if agg['function'] == 'COUNT' and agg['column'] == '*':
                        agg_funcs.append("COUNT(*)")
                    else:
                        agg_funcs.append(f"{agg['function']}({agg['column']})")
                print(f"  聚合函数: {', '.join(agg_funcs)}")
        
        elif plan['type'] == 'DELETE':
            print(f"DELETE FROM: {plan['table_name']}")
            if plan['where_clause']:
                print("  WHERE条件: 已设置")
        
        elif plan['type'] == 'UPDATE':
            print(f"UPDATE: {plan['table_name']}")
            print("  SET:")
            for assignment in plan['assignments']:
                print(f"    {assignment['column']} = {assignment['value']['value']}")
            if plan['where_clause']:
                print("  WHERE条件: 已设置")
        
        elif plan['type'] == 'DROP_TABLE':
            print(f"DROP_TABLE: {plan['table_name']}")

def main():
    """测试SQL编译器"""
    compiler = SQLCompilerV3()
    
    # 测试SQL语句
    test_sqls = [
        "CREATE TABLE tst1 (id INT, name VARCHAR(50), age INT);",
        "INSERT INTO tst1 VALUES (1, 'Alice', 25);",
        "SELECT * FROM tst1 WHERE age > 20;",
        "DELETE FROM tst1 WHERE age > 20;"
    ]
    
    for sql in test_sqls:
        print(f"编译SQL: {sql}")
        result = compiler.compile(sql)
        compiler.print_compile_result(result)
        print("\n" + "="*80 + "\n")
    
    # 打印编译统计
    stats = compiler.get_compile_stats()
    print("编译统计:")
    print(f"  总语句数: {stats['total_statements']}")
    print(f"  成功编译: {stats['successful_compiles']}")
    print(f"  词法错误: {stats['lexical_errors']}")
    print(f"  语法错误: {stats['syntax_errors']}")
    print(f"  语义错误: {stats['semantic_errors']}")
    
    # 打印系统目录
    print("\n系统目录:")
    compiler.print_catalog()

if __name__ == "__main__":
    main()